{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `$PROFILE` Support in a PowerShell Notebook <img src=\"https://raw.githubusercontent.com/PowerShell/PowerShell/master/assets/Powershell_black_64.png\" align=\"right\"/>\n",
    "\n",
    "For a while now, PowerShell has had this concept of \"Profiles\" which are scripts that run when a new instance of PowerShell is started. Inside of a profile, you can put any PowerShell script you'd like.\n",
    "\n",
    "To see the location of the profile, simply run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$PROFILE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can create that file and fill it with anything you want to run before your Notebook runs the first cell of the session.\n",
    "\n",
    "This profile path is specific to .NET Interactive and specific to the current user who's running it.\n",
    "\n",
    "### Give it a try\n",
    "\n",
    "Let's add a definition of a global variable to our profile:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "'$global:SET_IN_PROFILE = $true' >> $PROFILE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Now open a new Notebook and try running `$global:SET_IN_PROFILE`. It should be set to `True`!*\n",
    "\n",
    "### Profiles come in many flavors\n",
    "\n",
    "In PowerShell, you often see a few different kinds of profiles that are accessible [on the `$PROFILE` object](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_profiles?#the-profile-variable). Just running `$PROFILE` is actually the same as running `$PROFILE.CurrentUserCurrentHost`. Here are the possibilities:\n",
    "\n",
    "|`$PROFILE` Property Name|Description|\n",
    "|:------------------------|:-----------|\n",
    "|`$PROFILE.CurrentUserCurrentHost`|The current user for the current host|\n",
    "|`$PROFILE.AllUsersCurrentHost`|All users for the current host|\n",
    "|`$PROFILE.CurrentUserAllHosts`|The current user for all hosts|\n",
    "|`$PROFILE.AllUsersAllHost`|All users for all hosts|\n",
    "\n",
    "> NOTE: A \"host\" here refers to a PowerShell Host application or a \"PSHost\". These are applications that host a PowerShell runtime. Examples of these include:\n",
    "> * ConsoleHost (used by `pwsh.exe`/`pwsh`)\n",
    "> * PowerShell Editor Services Host (used by the PowerShell extension for Visual Studio Code's PowerShell Integrated Console)\n",
    "> * .NET Interactive Host (used by this experience in .NET Interactive)\n",
    "\n",
    "Check out [the PowerShell documentation](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_profiles?#the-profile-variable) on the `$PROFILE` object for more information.\n",
    "\n",
    "### Differences in .NET Interactive's Profile implementation\n",
    "\n",
    "With all that said, .NET Interactive doesn't perfectly align with PowerShell profiles for a few good reasons:\n",
    "\n",
    "#### There is no support for `$PROFILE.CurrentUserAllHosts` or `$PROFILE.AllUsersAllHosts`\n",
    "\n",
    "A lot of folks customize their PowerShell prompt in the `$PROFILE.CurrentUserAllHosts` or `$PROFILE.AllUsersAllHosts` profiles. .NET Interactive doesn't have a concept of a prompt. Because of this, .NET Interactive does not run your `$PROFILE.CurrentUserAllHosts` or `$PROFILE.AllUsersAllHosts` profiles. If you feel like this isn't the right behavior, let us know!\n",
    "\n",
    "#### `$PROFILE.AllUsersCurrentHost` isn't in a system-wide location\n",
    "\n",
    "Try running it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$PROFILE.AllUsersCurrentHost"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You'll notice that it exists in the location that .NET Interactive was installed to.\n",
    "\n",
    "This is typical for the `AllUsersCurrentHost` profile as it typically installs in the result of:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$PSHOME"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, since .NET Interactive is a .NET Tool there is no such thing as a system-wide installation, so `AllUsersCurrentHost` path is where it is today."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (PowerShell)",
   "language": "PowerShell",
   "name": ".net-powershell"
  },
  "language_info": {
   "file_extension": ".ps1",
   "mimetype": "text/x-powershell",
   "name": "PowerShell",
   "pygments_lexer": "powershell",
   "version": "7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}